package org.rcy.framework.data.util;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Transient;

public class PersistentUtil {
    public PersistentUtil() {
    }

    public static String getTableName(Class<?> clazz) {
        return getTableName(clazz, true);
    }

    public static String getTableName(Class<?> clazz, boolean camelToUnderline) {
        if (clazz.isAnnotationPresent(Table.class)) {
            Table table = (Table)clazz.getAnnotation(Table.class);
            if (!"".equals(table.name().trim())) {
                return table.name();
            }
        }

        String className = clazz.getSimpleName();
        return !camelToUnderline ? className : NamingUtil.camelToUnderline(className);
    }

    public static String getColumnName(Field field) {
        return getColumnName(field, true);
    }

    public static String getColumnName(Field field, boolean camelToUnderline) {
        if (field.isAnnotationPresent(Column.class)) {
            Column column = (Column)field.getAnnotation(Column.class);
            if (!"".equals(column.name().trim())) {
                return column.name().toUpperCase();
            }
        }

        return !camelToUnderline ? field.getName() : NamingUtil.camelToUnderline(field.getName());
    }

    public static String getMappedName(Field field) {
        if (field.isAnnotationPresent(OneToOne.class)) {
            OneToOne one = (OneToOne)field.getAnnotation(OneToOne.class);
            if (!one.mappedBy().trim().equals("")) {
                return one.mappedBy();
            }
        }

        if (field.isAnnotationPresent(OneToMany.class)) {
            OneToMany one = (OneToMany)field.getAnnotation(OneToMany.class);
            if (!one.mappedBy().trim().equals("")) {
                return one.mappedBy();
            }
        }

        return null;
    }

    public static List<Field> getPersistentFields(Class<?> clazz) {
        List<Field> list = new ArrayList();

        for(Class<?> searchType = clazz; !Object.class.equals(searchType) && searchType != null; searchType = searchType.getSuperclass()) {
            Field[] fields = searchType.getDeclaredFields();
            Field[] var4 = fields;
            int var5 = fields.length;

            for(int var6 = 0; var6 < var5; ++var6) {
                Field field = var4[var6];
                if (isPersistentField(field)) {
                    list.add(field);
                }
            }
        }

        return list;
    }

    public static Field getIdField(Class<?> clazz) {
        for(Class<?> searchType = clazz; !Object.class.equals(searchType) && searchType != null; searchType = searchType.getSuperclass()) {
            Field[] fields = searchType.getDeclaredFields();
            Field[] var3 = fields;
            int var4 = fields.length;

            for(int var5 = 0; var5 < var4; ++var5) {
                Field field = var3[var5];
                if (field.isAnnotationPresent(Id.class) && isPersistentField(field)) {
                    return field;
                }
            }
        }

        return null;
    }

    public static boolean insertable(Field field) {
        if (isPersistentField(field) && !isAssociationField(field)) {
            if (field.isAnnotationPresent(Column.class)) {
                Column column = (Column)field.getAnnotation(Column.class);
                return column.insertable();
            } else {
                return true;
            }
        } else {
            return false;
        }
    }

    public static boolean updatable(Field field) {
        if (isPersistentField(field) && !isAssociationField(field)) {
            if (field.isAnnotationPresent(Column.class)) {
                Column column = (Column)field.getAnnotation(Column.class);
                return column.updatable();
            } else {
                return true;
            }
        } else {
            return false;
        }
    }

    public static boolean isPersistentField(Field field) {
        return !Modifier.isStatic(field.getModifiers()) && !field.isAnnotationPresent(Transient.class);
    }

    public static boolean isAssociationField(Field field) {
        return field.isAnnotationPresent(OneToOne.class) || field.isAnnotationPresent(OneToMany.class);
    }
}
